﻿using GN.Pay.TradeChannel.DefaultImpl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.AliPay.Response
{
    /// <summary>
    /// 付款通知响应实体
    /// </summary>
    [Serializable]
    public class PayNotifyResponseEntity : NotifyResponseEntity
    {
        /// <summary>
        /// 商户网站唯一订单号,对应商户网站的订单系统中的唯一订单号，非支付宝交易号。
        /// </summary>
        public string Out_Trade_No { get; set; }

        /// <summary>
        /// 商品名称
        /// </summary>
        public string Subject { get; set; }

        /// <summary>
        /// 支付类型,只支持取值为1（商品购买）。
        /// </summary>
        public string Payment_type { get; set; }

        /// <summary>
        /// 支付宝交易号
        /// </summary>
        public string Trade_No { get; set; }

        /// <summary>
        /// 交易状态 
        /// <para>WAIT_BUYER_PAY 交易创建，等待买家付款。</para>
        /// <para>TRADE_CLOSED 在指定时间段内未支付时关闭的交易；在交易完成全额退款成功时关闭的交易</para>
        /// <para>TRADE_SUCCESS 交易成功，且可对该交易做操作，如：多级分润、退款等。</para>
        /// <para>TRADE_PENDING 等待卖家收款（买家付款后，如果卖家账号被冻结）。</para>
        /// <para>TRADE_FINISHED 交易成功且结束，即不可再做任何操作。</para>
        /// </summary>
        public string Trade_Status { get; set; }

        /// <summary>
        /// 交易创建时间
        /// </summary>
        public DateTime? Gmt_Create { get; set; }

        /// <summary>
        /// 交易付款时间
        /// </summary>
        public DateTime? Gmt_Payment { get; set; }

        /// <summary>
        /// 交易关闭时间
        /// </summary>
        public DateTime? Gmt_close { get; set; }

        /// <summary>
        /// 交易退款状态
        /// <para>REFUND_SUCCESS 退款成功 全额退款情况：trade_status= TRADE_CLOSED，而refund_status=REFUND_SUCCESS
        /// 非全额退款情况：trade_status= TRADE_SUCCESS，而refund_status=REFUND_SUCCESS</para>
        /// <para>REFUND_CLOSED 退款关闭</para>
        /// </summary>
        public string Refund_Status { get; set; }

        /// <summary>
        /// 退款时间
        /// </summary>
        public DateTime? Gmt_Refund { get; set; }

        /// <summary>
        /// 卖家支付宝账号
        /// </summary>
        public string Seller_Email { get; set; }

        /// <summary>
        /// 买家支付宝账号
        /// </summary>
        public string Buyer_Email { get; set; }

        /// <summary>
        /// 卖家支付宝账户号
        /// </summary>
        public string Seller_Id { get; set; }

        /// <summary>
        /// 买家支付宝账户号
        /// </summary>
        public string Buyer_Id { get; set; }

        /// <summary>
        /// 商品单价
        /// </summary>
        public decimal? Price { get; set; }

        /// <summary>
        /// 交易金额
        /// </summary>
        public decimal? Total_Fee { get; set; }

        /// <summary>
        /// 购买数
        /// </summary>
        public int? Quantity { get; set; }

        /// <summary>
        /// 商品描述
        /// </summary>
        public string Body { get; set; }

        /// <summary>
        /// 公用回传参数
        /// </summary>
        public string Extra_Common_Param { get; set; }

        #region app

        /// <summary>
        /// 
        /// </summary>
        public string App_id { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Charset { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Version { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Buyer_Logon_Id { get; set; }

        /// <summary>
        /// 本次交易支付的订单金额，单位为人民币
        /// </summary>
        public decimal? Total_Amount { get; set; }

        /// <summary>
        /// 商家在交易中实际收到的款项，单位为元
        /// </summary>
        public decimal? Receipt_Amount { get; set; }

        /// <summary>
        /// 用户在交易中支付的金额
        /// </summary>
        public decimal? Buyer_Pay_Amount { get; set; }

        #endregion

        private decimal? GetPayMoney()
        {
            if (this.Total_Fee != null && this.Total_Fee.Value > 0m)
            {
                return this.Total_Fee.Value;
            }
            if (Total_Amount != null && Total_Amount.Value > 0)
            {
                return Total_Amount.Value;
            }
            if (Buyer_Pay_Amount != null && Buyer_Pay_Amount.Value > 0)
            {
                return Buyer_Pay_Amount.Value;
            }
            return null;
        }

        /// <summary>
        /// 获取是否成功
        /// </summary>
        public bool IsSuccess()
        {
            return "TRADE_SUCCESS".Equals(this.Trade_Status, StringComparison.InvariantCultureIgnoreCase)
                    || "TRADE_FINISHED".Equals(this.Trade_Status, StringComparison.InvariantCultureIgnoreCase);
        }

        /// <summary>
        /// 转换为查询结果
        /// </summary>
        /// <param name="channel">通知</param>
        /// <returns></returns>
        public ITradeOrderQueryResult ToPayResult(ITradeChannel channel)
        {
            if (string.IsNullOrWhiteSpace(this.Out_Trade_No))
            {
                channel.ThrowChannelValidationException("支付宝交易付款通知的商户订单号为null或空白。");
            }
            if (string.IsNullOrWhiteSpace(this.Trade_No))
            {
                channel.ThrowChannelValidationException("支付宝交易付款通知的平台交易号为null或空白。");
            }
            var money = GetPayMoney();
            if (money == null || money.Value <= 0)
            {
                channel.ThrowChannelValidationException("支付宝交易付款通知总金额小于或等于零。");
            }
            if (this.Gmt_Payment == null)
            {
                channel.ThrowChannelValidationException("支付宝交易付款通知付款时间为 null。");
            }
            return new TradeOrderQueryResult(channel)
            {
                OrderNo = this.Out_Trade_No,
                PayTime = this.Gmt_Payment.Value,
                TradeNo = this.Trade_No,
                OrderMoney = money.Value,
                Subject = this.Subject,
                Body = this.Body,
                ExtraParam = this.Extra_Common_Param,
                OtherPartyAccount = this.Buyer_Email,
                OtherPartyAccountId = this.Buyer_Id,
                PayFee = 0m,
                RefundFee = 0m,
                RefundMoney = 0m
            };
        }
    }
}
